# vim: syntax=make foldmarker=<([{,}])> foldmethod=marker

# 1) Common rules <([{
.SECONDARY: # Reserve all intermediate files.

$(OBJ_PATH)/%fix.test.elf: $(OBJ_PATH)/ossym.list
	ld --eh-frame-hdr -Map $(basename $@).map -T fix.ld --just-symbols=$(OBJ_PATH)/ossym.list -o $@ $(OBJ_PATH)/$(ELFO_BASENAME)fix.test.o
$(OBJ_PATH)/%pic.test.elf: $(OBJ_PATH)/ossym.list
	ld --eh-frame-hdr -shared -Map $(basename $@).map -T pic.ld --just-symbols=$(OBJ_PATH)/ossym.list -o $@ $(OBJ_PATH)/$(ELFO_BASENAME)pic.test.o

$(OBJ_PATH)/%.dep: %.c
	@mkdir -p $(OBJ_PATH)
	g++ -I$(INCLUDEPATH)/ -E -MM -MF $@ -MT '$@' $<
$(OBJ_PATH)/%.dep: %.S
	@mkdir -p $(OBJ_PATH)
	gcc -I$(INCLUDEPATH)/ -E -MM -MF $@ -MT '$@' $<
$(OBJ_PATH)/%.dep: %.cc
	@mkdir -p $(OBJ_PATH)
	g++ -I$(INCLUDEPATH)/ -E -MM -MF $@ -MT '$@' $<

$(OBJ_PATH)/%.test.o: %.test.cc $(OBJ_PATH)/%.test.dep
	g++ -I$(TESTINCLUDEPATH)/ -I$(INCLUDEPATH)/ $(TESTCXXFLAGS) -c -o $@ $<

$(OBJ_PATH)/%.o: %.c $(OBJ_PATH)/%.dep
	gcc -I$(INCLUDEPATH)/ $(CFLAGS) -c -o $@ $<
$(OBJ_PATH)/%.o: %.S $(OBJ_PATH)/%.dep
	gcc -I$(INCLUDEPATH)/ $(ASFLAGS) -c -o $@ $<
$(OBJ_PATH)/%.o: %.cc $(OBJ_PATH)/%.dep
	g++ -I$(INCLUDEPATH)/ $(CXXFLAGS) -c -o $@ $<
# }])>

# 2) make <PACKAGE NAME>.package.o of current package. <([{
ifeq ($(MAKECMDGOALS), )
PACKAGE_O := $(patsubst %, $(OBJ_PATH)/%.package.o, $(PACKAGE_NAME))
PACKAGE_FILES := $(basename $(filter-out $(wildcard *.test.cc), $(wildcard *.S *.cc *.c)))
PACKAGE_DEPEND_FILES := $(patsubst %, $(OBJ_PATH)/%.dep, $(PACKAGE_FILES))
PACKAGE_OBJS := $(patsubst %, $(OBJ_PATH)/%.o, $(PACKAGE_FILES))
# @todo@: immigrating sub-packages to current package doesn't be implemented!
SUB_PACKAGE_OBJS := 
ifneq ($(strip $(PACKAGE_DEPEND_FILES)), )
-include $(PACKAGE_DEPEND_FILES)
endif
$(PACKAGE_O): $(PACKAGE_OBJS) $(SUB_PACKAGE_OBJS)
	ld -r -o $@ $^
.PHONY: package_rule
package_rule: $(PACKAGE_O)
endif
# }])>

# 3) rule about cleaning files. <([{
ifeq ($(MAKECMDGOALS), clean)
.PHONY: clean_rule
clean_rule:
	rm -f $(OBJ_PATH)/*
endif
# }])>

# 4) make and run test cases. <([{
# @todo@: suffix .unittest.cc is used as class unit test, while .integrationtest.cc is used as integration test.
# @todo@: Until now, only support testing .cc not `.c .S'.
ifeq ($(NEED_TEST), true)
TEST_FILES := $(basename $(wildcard  *.test.cc))
TEST_DEPEND_FILES := $(patsubst %, $(OBJ_PATH)/%.dep, $(TEST_FILES))
TEST_OBJS := $(patsubst %, $(OBJ_PATH)/%.o, $(TEST_FILES))
ifneq ($(strip $(TEST_DEPEND_FILES)), )
-include $(TEST_DEPEND_FILES)
endif
.PHONY: test_rule
test_rule: $(TEST_OBJS)
endif
# }])>

# 5) make sub-directory <([{
ifneq ($(strip $(SUBDIR_LIST)), )
.PHONY: subdir_rule $(SUBDIR_LIST)
$(SUBDIR_LIST):
	make -C $@ $(MAKECMDGOALS)
subdir_rule: $(SUBDIR_LIST)
endif
# }])>

# 6) ctages/cscope <([{
ifeq ($(MAKECMDGOALS), tags)
.PHONY: tags_rule
tags_rule:
	cd $(TOPDIR) && cscope -bR
	ctags --append=no --recurse=yes -f $(TOPDIR)/tags
endif
# }])>

# 7) synchronize cvs repository. <([{
# The section is discarded, I will migrate it to svn in future.
# @todo@: synchronize directory.
ifeq ($(MAKECMDGOALS), cvs)
CVS_REPOSITORY := $(shell cvs -n update 2>/dev/null)
ADD_TO_CVS := $(shell echo $(CVS_REPOSITORY) | awk '{for(i = 1; i <= NF; i+=2) if($$i == "?") printf("%s ", $$(i + 1));}')
DEL_FROM_CVS := $(shell echo $(CVS_REPOSITORY) | awk '{for(i = 1; i <= NF; i+=2) if($$i == "U") printf("%s ", $$(i + 1));}')
.PHONY: cvs_rule
cvs_rule:
	@echo ADD:$(ADD_TO_CVS)
	@for i in $(ADD_TO_CVS); do \
		if [ -f $$i ]; then \
			cvs add $$i; \
		fi; \
	done
	@echo DEL:$(DEL_FROM_CVS)
	@for i in $(DEL_FROM_CVS); do \
		cvs remove $$i; \
	done
endif
# }])>

# 8) patch <([{
# @todo@ The section is used to immitate `quilt' tool. It automatically add file to patch list according to current file modifying time and svn repository.
# }])>
